package com.merry.beanFactory.ac;

import java.io.Closeable;

import com.merry.ConversionService.ConversionService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.Lifecycle;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ProtocolResolver;
import org.springframework.lang.Nullable;

/**
 * 一个可以配置的 ApplicationContext 对象，它额外实现了 {@link Lifecycle} 、 {@link Closeable}
 *      Lifecycle：这个接口中定义了，容器的启动、停止、是否在运行。
 *      Closeable：自动关闭的接口。实现了这个接口，就意味着这个类可以调用 close 方法关闭接口。
 */
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {

    /**
     * Any number of these characters are considered delimiters between
     * multiple context config paths in a single String value.
     */
    String CONFIG_LOCATION_DELIMITERS = ",; \t\n";

    /**
     * 类型转换服务的 beanName。{@link ConversionService}
     */
    String CONVERSION_SERVICE_BEAN_NAME = "conversionService";

    /**
     * LoadTimeAwarer 接口的 beanName。
     */
    String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";

    String ENVIRONMENT_BEAN_NAME = "environment";

    String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";

    String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";

    String SHUTDOWN_HOOK_THREAD_NAME = "SpringContextShutdownHook";


    /**
     * 设置容器的 ID
     */
    void setId(String id);

    /**
     * 设置容器的父容器。
     */
    void setParent(@Nullable ApplicationContext parent);

    /**
     * 设置容器的环境
     */
    void setEnvironment(ConfigurableEnvironment environment);

    /**
     * 获取容器的环境。
     */
    @Override
    ConfigurableEnvironment getEnvironment();

    /**
     * 添加一个新的 BeanFactoryPostProcessor，它支持用户自己修改一个已经创建的 BeanFactory 容器。
     */
    void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor);

    /**
     * 添加一个 ApplicationListener 事件监听器。
     */
    void addApplicationListener(ApplicationListener<?> listener);

    /**
     * 设置类加载器。
     */
    void setClassLoader(ClassLoader classLoader);

    void addProtocolResolver(ProtocolResolver resolver);

    /**
     * 一个核心的方法：在Spring的启动中会看到这个方法。
     *      这是一种启动方法，如果失败，它应该销毁已经创建的单例。
     *      以避免悬挂资源。换句话说，在调用此方法后，应实例化全部或根本不实例化实例。
     */
    void refresh() throws BeansException, IllegalStateException;

    /**
     * 注册一个钩子函数。在容器关闭的时候会调用这个函数。
     */
    void registerShutdownHook();

    /**
     * 容器的关闭方法。
     */
    @Override
    void close();

    boolean isActive();

    /**
     * 获取一个 BeanFactory 对象。
     */
    ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;

}

